<?php

namespace app\admin\controller;


use \think\facade\Filesystem;
use app\admin\controller\BaseController;
use app\common\exception\MessageException;
use app\common\model\mysql\DriverFile;

class Upload extends BaseController
{

    /**
     * TODO: 1、上传文件类型判断限制；2、文件大小限制；3、文件分文件夹管理
     * image 图片 bmp,png,jpg,jpeg,tif,gif,psd,ai,raw,webp
     * video 视频 wmv,asf,asx,rm,rmvb,mp4,3gp,mov,m4v,aiv,mkv,flv,vob,avi
     * audio 音频 wav,flac,ape,alac,wv,mp3,acc,ogg
     * document 文档 pdf,doc,docx,xlsx,xls,csv
     * hybrid 压缩包 zip,rar,7z
     * files 格外允许上传 先不配置
     * 未定义 unknown 不允许上传
     */
    private $fileSize = 1024 * 1024 * 100; // 单文件大小限制100MB
    private $image = array('bmp', 'png', 'jpg', 'jpeg', 'tif', 'gif', 'psd', 'ai', 'raw', 'webp');
    private $video = array('wmv', 'asf', 'asx', 'rm', 'rmvb', 'mp4', '3gp', 'mov', 'm4v', 'aiv', 'mkv', 'flv', 'vob', 'avi');
    private $audio = array('wav', 'flac', 'ape', 'alac', 'wv', 'mp3', 'acc', 'ogg');
    private $document = array('pdf', 'doc', 'docx', 'xlsx', 'xls', 'csv');
    private $hybrid = array('zip', 'rar', '7z');

    public function getFileDir($fileExt): string
    {
        if (in_array($fileExt, $this->image)) {
            return 'image';
        }
        if (in_array($fileExt, $this->video)) {
            return 'video';
        }
        if (in_array($fileExt, $this->audio)) {
            return 'audio';
        }
        if (in_array($fileExt, $this->document)) {
            return 'document';
        }
        if (in_array($fileExt, $this->hybrid)) {
            return 'hybrid';
        }
        return '';
    }

    /**
     * 返回数据库对应文件类型
     * 10 图片 20 视频 30 音频 40 文档 50 压缩包
     * @param $fileExt
     * @return string
     */
    public function getFileType($fileExt): string
    {
        if (in_array($fileExt, $this->image)) {
            return 10;
        }
        if (in_array($fileExt, $this->video)) {
            return 20;
        }
        if (in_array($fileExt, $this->audio)) {
            return 30;
        }
        if (in_array($fileExt, $this->document)) {
            return 40;
        }
        if (in_array($fileExt, $this->hybrid)) {
            return 50;
        }
        return '';
    }

    /**
     * 单文件上传
     */
    public function index()
    {
        if (!$this->request->isPost()) {
            throw new MessageException(['msg' => '请求方法不合法']);
        }

        // 获取表单上传文件 例如上传了001.jpg
        $params = request()->param();
        $file = request()->file('file');
        // 文件数据
        $data['folder_id'] = $params['folder_id'] ?? 0;
        $data['file_size'] = $file->getSize();
        if ($data['file_size'] > $this->fileSize) {
            throw new MessageException(['msg' => '文件超出大小限制']);
        }

        $data['status'] = 1;
        $data['is_recycle'] = 0;
        $data['file_ext'] = $file->getOriginalExtension();
        $data['file_name'] = basename($file->getOriginalName(), '.'.$data['file_ext']);
        $data['file_type'] = $this->getFileType($data['file_ext']);

        $fileDir = $this->getFileDir($data['file_ext']);
        if (!$fileDir) {
            throw new MessageException(['msg' => '文件类型不合法']);
        }

        $saveName = Filesystem::disk('public')->putFile($fileDir, $file);
        // /upload/video/20230802/e3684841a6c1f16c144324b4bf584a9a.mp4
        // http://zen.localhost.com/storage/upload/video/20230802/e3684841a6c1f16c144324b4bf584a9a.mp4
        $data['file_path'] = str_replace("\\", '/', '/' . $saveName);
        // 保存数据库记录
        try {
            $result = (new DriverFile())->create($data);
            if ($result) {
                return $this->renderSuccess(['path' => $data['file_path']]);
            } else {
                return $this->renderFail('保存失败');
            }
        } catch (\Exception $e) {
            throw new MessageException(['msg' => $e->getMessage()]);
        }
    }

    /**
     * 多文件上传
     * multiple Upload
     */
    public function multiple()
    {
        if (!$this->request->isPost()) {
            throw new MessageException(['msg' => '请求方法不合法']);
        }
        // 获取表单上传文件
        $params = request()->param();
        $files = request()->file();
        $Model = new DriverFile();
        // 结果集
        $saveFile = [];
        $data = array();
        foreach ($files as $key => $file) {
            $data[$key]['folder_id'] = $params['folder_id'] ?? 0;
            $data[$key]['status'] = 1;
            $data[$key]['is_recycle'] = 0;
            $data[$key]['file_size'] = $file->getSize();
            $data[$key]['file_ext'] = $file->getOriginalExtension();
            $data[$key]['file_name'] = basename($file->getOriginalName(), '.'.$data[$key]['file_ext']);
            $data[$key]['file_type'] = $this->getFileType($data[$key]['file_ext']);
            $fileDir = $this->getFileDir($data[$key]['file_ext']);
            if ($data[$key]['file_size'] > $this->fileSize) {
                $saveFile[] = [$data[$key]['file_name'] => '文件超出大小限制'];
            } else {
                if (!$fileDir) {
                    $saveFile[] = [$data[$key]['file_name'] => '文件类型不合法'];
                } else {
                    $saveName = Filesystem::disk('public')->putFile($fileDir, $file);
                    $data[$key]['file_path'] = str_replace("\\", '/', '/' . $saveName);

                    // 保存数据库记录
                    try {
                         $result = $Model->create($data[$key]);
//                        $result = $Model->isUpdate(false)->data($data[$key], true)->create();
                        if ($result) {
                            // 保存数据库记录
                            $saveFile[] = [$data[$key]['file_name'] => $data[$key]['file_path']];
                        } else {
                            $saveFile[] = [$data[$key]['file_name'] => '保存失败'];
                        }
                    } catch (\Exception $e) {
                        $saveFile[] = [$data[$key]['file_name'] => $e->getMessage()];
                        // throw new MessageException(['msg' => $e->getMessage()]);
                    }
                }
            }
        }
        return $this->renderSuccess($saveFile);
    }
}
